import os
import subprocess
import random
import time
import tempfile
from pathlib import Path
from typing import Dict, Any, Optional, List, Tuple
import cv2
import numpy as np
from src.utils.logger import log_info, log_error, log_warning

class WatermarkGenerator:
    """用于生成透明浮动水印并合并到视频的工具类"""
    
    def __init__(self):
        """初始化水印生成器"""
        self.ffmpeg_path = "ffmpeg"  # 假设ffmpeg已添加到PATH
        self.temp_dir = tempfile.gettempdir()
    
    def add_floating_text_watermark(
        self,
        video_path: str,
        output_path: str,
        text: str,
        font_size: int = 36,
        font_color: str = "white",
        opacity: float = 1,
        movement_type: str = "random",
        font_file: Optional[str] = None,
        speed: float = 1.0
    ) -> Dict[str, Any]:
        """
        将透明浮动文本水印添加到视频。
        
        Args:
            video_path: 输入视频路径
            output_path: 输出视频路径
            text: 水印文本内容
            font_size: 字体大小
            font_color: 字体颜色
            opacity: 不透明度 (0.0-1.0)
            movement_type: 移动类型 ("random", "diagonal", "bounce", "circular")
            font_file: 可选的字体文件路径
            speed: 水印移动速度 (0.5-3.0)
            
        Returns:
            包含处理结果的字典
        """
        try:
            # 检查输入文件是否存在
            if not os.path.exists(video_path):
                return {"success": False, "message": f"输入视频不存在: {video_path}"}
            
            # 确保输出目录存在
            os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True)
            
            # 获取视频信息
            video_info = self._get_video_info(video_path)
            if not video_info["success"]:
                return video_info
            
            width = video_info["width"]
            height = video_info["height"]
            duration = video_info["duration"]
            
            # 生成水印移动表达式
            movement_expr = self._generate_movement_expression(
                width, height, font_size, movement_type, speed, duration, text
            )
            
            # 构建FFmpeg命令
            cmd = self._build_ffmpeg_command(
                video_path, 
                output_path, 
                text, 
                font_size, 
                font_color, 
                opacity, 
                movement_expr, 
                font_file
            )
            
            # 执行FFmpeg命令
            log_info(f"开始添加浮动水印到视频: {video_path}")
            process = subprocess.Popen(
                cmd, 
                stdout=subprocess.PIPE, 
                stderr=subprocess.PIPE,
                universal_newlines=True
            )
            _, stderr = process.communicate()
            
            # 检查处理结果
            if process.returncode != 0:
                log_error(f"添加水印失败: {stderr}")
                return {"success": False, "message": "添加水印失败", "error": stderr}
            
            if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
                log_info(f"水印添加成功，输出文件: {output_path}")
                return {
                    "success": True,
                    "message": "水印添加成功",
                    "output_path": output_path,
                    "video_info": video_info
                }
            else:
                log_error("输出文件生成失败或为空")
                return {"success": False, "message": "输出文件生成失败或为空"}
                
        except Exception as e:
            log_error(f"处理视频水印时发生错误: {e}")
            return {"success": False, "message": f"处理错误: {str(e)}"}
    
    def _get_video_info(self, video_path: str) -> Dict[str, Any]:
        """获取视频的基本信息"""
        try:
            cap = cv2.VideoCapture(video_path)
            if not cap.isOpened():
                return {"success": False, "message": "无法打开视频文件"}
            
            width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
            height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
            fps = cap.get(cv2.CAP_PROP_FPS)
            frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
            duration = frame_count / fps if fps > 0 else 0
            
            cap.release()
            
            return {
                "success": True,
                "width": width,
                "height": height,
                "fps": fps,
                "frame_count": frame_count,
                "duration": duration
            }
        except Exception as e:
            log_error(f"获取视频信息失败: {e}")
            return {"success": False, "message": f"获取视频信息失败: {str(e)}"}
    
    def _generate_movement_expression(
        self,
        width: int,
        height: int,
        font_size: int,
        movement_type: str,
        speed: float,
        duration: float,
        text: str  # 新增参数
    ) -> Dict[str, str]:
        """
        生成水印移动的表达式，根据实际文本内容确保水印始终保持在视频可见范围内
        
        Args:
            width: 视频宽度
            height: 视频高度
            font_size: 字体大小
            movement_type: 移动类型
            speed: 移动速度
            duration: 视频时长
            text: 水印文本内容
        
        Returns:
            包含x和y表达式的字典
        """
        # 分析文本内容
        lines = text.split('\n')
        line_count = len(lines)
        max_chars_per_line = max(len(line) for line in lines)
        speed = speed * 1000
        # 估算单个字符的尺寸
        char_width = font_size * 0.7  # 汉字约为0.9-1.0，英文约为0.5-0.6
        char_height = font_size * 1.2  # 行高通常为字体大小的1.2-1.5倍
        
        # 计算文本区域大小
        text_width = max_chars_per_line * char_width
        text_height = line_count * char_height
        
        # 如果文本过长，考虑自动换行
        if text_width > width * 0.7 and '\n' not in text and len(text) > 10:
            # 估计每行可以容纳的字符数
            chars_per_line = int(width * 0.7 / char_width)
            # 重新计算行数和文本高度
            line_count = (len(text) + chars_per_line - 1) // chars_per_line
            text_height = line_count * char_height
            text_width = min(text_width, width * 0.7)
            
            log_info(f"文本过长，建议使用换行: 行数={line_count}, 宽度={text_width:.1f}, 高度={text_height:.1f}")
        
        # 计算安全活动区域，考虑实际文本大小
        margin_x = text_width * 0.1 + 20  # 额外安全边距
        margin_y = text_height * 0.1 + 20
        
        min_x = margin_x
        max_x = width - text_width - margin_x
        min_y = margin_y
        max_y = height - text_height - margin_y
        
        # 检查活动区域是否有效
        if max_x <= min_x or max_y <= min_y:
            # 如果文本太大，无法满足安全边距，则缩小边距
            min_x = 10
            max_x = width - text_width - 10
            min_y = 10
            max_y = height - text_height - 10
            
            log_warning(f"文本尺寸过大或视频分辨率过小，减少安全边距: x({min_x:.1f}-{max_x:.1f}), y({min_y:.1f}-{max_y:.1f})")
            
            # 如果仍然无效，则使用固定位置
            if max_x <= min_x or max_y <= min_y:
                log_warning("无法找到合适的活动区域，使用中心固定位置")
                return {
                    "x": f"(w-text_w)/2",
                    "y": f"(h-text_h)/2"
                }
        
        # 计算活动区域中心点和范围
        x_center = (min_x + max_x) / 2
        y_center = (min_y + max_y) / 2
        x_range = max(1, (max_x - min_x) / 2.5)  # 确保至少有一个像素的活动范围
        y_range = max(1, (max_y - min_y) / 2.5)
        
        # 为多行文本调整移动模式 - 多行文本建议使用较慢移动或静止
        if line_count > 1:
            if movement_type not in ["static", "very_slow"]:
                log_info(f"多行文本({line_count}行)使用更慢的移动模式")
                movement_type = "very_slow"  # 多行文本默认使用极慢移动
        
        # 根据文本长度调整移动速度 - 文本越长移动越慢
        text_length_factor = min(1.0, 10.0 / max(10, len(text)))
        adjusted_speed = speed * 0.03 * text_length_factor  # 基础移动速度降低
        
        # 根据移动类型生成表达式
        expressions = {"x": f"{x_center}", "y": f"{y_center}"}        
        if movement_type == "random":
            # 随机轨迹 - 使用多个正弦/余弦函数叠加，频率非常低
            time_factor = adjusted_speed * 0.1
            
            basic_x = f"{x_center}+{x_range}*((sin(t*{time_factor})+sin(t*{time_factor*0.37})+sin(t*{time_factor*0.18}))/3)"
            basic_y = f"{y_center}+{y_range}*((cos(t*{time_factor*0.29})+cos(t*{time_factor*0.13})+cos(t*{time_factor*0.21}))/3)"
            
            expressions["x"] = basic_x
            expressions["y"] = basic_y
        
        # 应用最终安全边界检查 - 使用FFmpeg的text_w和text_h变量确保不会超出边界
        expressions["x"] = f"min(max({expressions['x']}, 10), w-text_w-10)"
        expressions["y"] = f"min(max({expressions['y']}, 10), h-text_h-10)"
        
        return expressions

    def add_floating_text_watermark(
        self,
        video_path: str,
        output_path: str,
        text: str,
        font_size: int = 36,
        font_color: str = "white",
        opacity: float = 0.3,
        movement_type: str = "random",
        font_file: Optional[str] = None,
        speed: float = 1.0
    ) -> Dict[str, Any]:
        """
        将透明浮动文本水印添加到视频。
        
        Args:
            video_path: 输入视频路径
            output_path: 输出视频路径
            text: 水印文本内容
            font_size: 字体大小
            font_color: 字体颜色
            opacity: 不透明度 (0.0-1.0)
            movement_type: 移动类型 ("random", "diagonal", "bounce", "circular")
            font_file: 可选的字体文件路径
            speed: 水印移动速度 (0.5-3.0)
            
        Returns:
            包含处理结果的字典
        """
        temp_files = []  # 存储需要清理的临时文件
        try:
            # 检查输入文件是否存在
            if not os.path.exists(video_path):
                return {"success": False, "message": f"输入视频不存在: {video_path}"}
            
            # 确保输出目录存在
            os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True)
            
            # 获取视频信息
            video_info = self._get_video_info(video_path)
            if not video_info["success"]:
                return video_info
            
            width = video_info["width"]
            height = video_info["height"]
            duration = video_info["duration"]
            
            # 生成水印移动表达式
            movement_expr = self._generate_movement_expression(
                width, height, font_size, movement_type, speed, duration, text
            )
            
            # 构建FFmpeg命令
            cmd, text_file_path = self._build_ffmpeg_command(
                video_path, 
                output_path, 
                text, 
                font_size, 
                font_color, 
                opacity, 
                movement_expr, 
                font_file
            )
            
            if text_file_path:
                temp_files.append(text_file_path)
            
            # 执行FFmpeg命令
            log_info(f"开始添加浮动水印到视频: {video_path}")
            process = subprocess.Popen(
                cmd, 
                stdout=subprocess.PIPE, 
                stderr=subprocess.PIPE,
                universal_newlines=True
            )
            _, stderr = process.communicate()
            
            # 检查处理结果
            if process.returncode != 0:
                log_error(f"添加水印失败: {stderr}")
                return {"success": False, "message": "添加水印失败", "error": stderr}
            
            if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
                log_info(f"水印添加成功，输出文件: {output_path}")
                return {
                    "success": True,
                    "message": "水印添加成功",
                    "output_path": output_path,
                    "video_info": video_info
                }
            else:
                log_error("输出文件生成失败或为空")
                return {"success": False, "message": "输出文件生成失败或为空"}
                
        except Exception as e:
            log_error(f"处理视频水印时发生错误: {e}")
            return {"success": False, "message": f"处理错误: {str(e)}"}
        finally:
            # 清理临时文件
            for temp_file in temp_files:
                try:
                    if os.path.exists(temp_file):
                        os.remove(temp_file)
                        log_info(f"已删除临时文件: {temp_file}")
                except Exception as e:
                    log_warning(f"删除临时文件失败: {e}")

    def _build_ffmpeg_command(
        self,
        input_path: str,
        output_path: str,
        text: str,
        font_size: int,
        font_color: str,
        opacity: float,
        movement_expr: Dict[str, str],
        font_file: Optional[str]
    ) -> Tuple[List[str], Optional[str]]:
        """构建FFmpeg命令，返回命令和临时文本文件路径"""
        # 创建临时文本文件
        text_file_path = os.path.join(self.temp_dir, f"watermark_text_{int(time.time()*1000)}.txt")
        
        # 确保文本内容以UTF-8编码写入文件
        with open(text_file_path, "w", encoding="utf-8") as f:
            f.write(text)
        
        # 准备drawtext滤镜参数
        font_args = f":fontsize={font_size}:fontcolor={font_color}@{opacity}"
        if font_file and os.path.exists(font_file):
            font_args += f":fontfile='{font_file}'"
        
        # 构建完整的drawtext滤镜字符串，使用textfile而非text
        drawtext_filter = f"drawtext=textfile='{text_file_path}'{font_args}:x='{movement_expr['x']}':y='{movement_expr['y']}':box=0:shadowcolor=black@0.2:shadowx=2:shadowy=2:text_shaping=1"
        
        # 构建完整的FFmpeg命令
        cmd = [
            self.ffmpeg_path,
            "-y",  # 覆盖输出文件（如果存在）
            "-i", input_path,
            "-vf", drawtext_filter,
            "-c:v", "libx264",  # 使用H.264编码
            "-crf", "23",       # 设置视频质量
            "-preset", "medium",  # 编码速度和质量的平衡
            "-c:a", "copy",     # 直接复制音频流
            output_path
        ]
        
        return cmd, text_file_path

    def add_multiple_watermarks(
        self,
        video_path: str,
        output_path: str,
        texts: List[str],
        font_sizes: Optional[List[int]] = None,
        font_colors: Optional[List[str]] = None,
        opacities: Optional[List[float]] = None,
        movement_types: Optional[List[str]] = None,
        font_file: Optional[str] = None,
        speeds: Optional[List[float]] = None
    ) -> Dict[str, Any]:
        """
        为视频添加多个浮动文本水印
        
        Args:
            video_path: 输入视频路径
            output_path: 输出视频路径
            texts: 水印文本列表
            font_sizes: 字体大小列表 (可选)
            font_colors: 字体颜色列表 (可选)
            opacities: 不透明度列表 (可选)
            movement_types: 移动类型列表 (可选)
            font_file: 字体文件路径 (可选)
            speeds: 移动速度列表 (可选)
            
        Returns:
            包含处理结果的字典
        """
        temp_files = []  # 存储需要清理的临时文件
        try:
            if not texts:
                return {"success": False, "message": "未提供水印文本"}
                
            # 初始化默认值列表
            n_watermarks = len(texts)
            if not font_sizes:
                font_sizes = [36] * n_watermarks
            if not font_colors:
                font_colors = ["white"] * n_watermarks
            if not opacities:
                opacities = [0.3] * n_watermarks
            if not movement_types:
                movement_types = ["random"] * n_watermarks
            if not speeds:
                speeds = [1.0] * n_watermarks
            
            # 确保所有列表长度一致
            if not all(len(lst) == n_watermarks for lst in [font_sizes, font_colors, opacities, movement_types, speeds]):
                return {"success": False, "message": "参数列表长度不一致"}
            
            # 获取视频信息
            video_info = self._get_video_info(video_path)
            if not video_info["success"]:
                return video_info
            
            width = video_info["width"]
            height = video_info["height"]
            duration = video_info["duration"]
            
            # 构建多个drawtext滤镜
            drawtext_filters = []
            
            for i in range(n_watermarks):
                # 为每个水印文本创建临时文本文件
                text_file_path = os.path.join(self.temp_dir, f"watermark_text_{i}_{int(time.time()*1000)}.txt")
                
                # 写入文本内容
                with open(text_file_path, "w", encoding="utf-8") as f:
                    f.write(texts[i])
                    
                temp_files.append(text_file_path)
                    
                movement_expr = self._generate_movement_expression(
                    width, height, font_sizes[i], movement_types[i], speeds[i], duration, texts[i]
                )
                
                font_args = f":fontsize={font_sizes[i]}:fontcolor={font_colors[i]}@{opacities[i]}"
                if font_file and os.path.exists(font_file):
                    font_args += f":fontfile='{font_file}'"
                
                # 使用textfile代替text
                drawtext = f"drawtext=textfile='{text_file_path}'{font_args}:x='{movement_expr['x']}':y='{movement_expr['y']}':box=0:shadowcolor=black@0.2:shadowx=2:shadowy=2:text_shaping=1"
                drawtext_filters.append(drawtext)
            
            # 组合所有滤镜
            combined_filters = ",".join(drawtext_filters)
            
            # 构建FFmpeg命令
            cmd = [
                self.ffmpeg_path,
                "-y",
                "-i", video_path,
                "-vf", combined_filters,
                "-c:v", "libx264",
                "-crf", "23",
                "-preset", "medium",
                "-c:a", "copy",
                output_path
            ]
            
            # 执行命令
            log_info(f"开始添加多个浮动水印到视频: {video_path}")
            process = subprocess.Popen(
                cmd, 
                stdout=subprocess.PIPE, 
                stderr=subprocess.PIPE,
                universal_newlines=True
            )
            _, stderr = process.communicate()
            
            if process.returncode != 0:
                log_error(f"添加多个水印失败: {stderr}")
                return {"success": False, "message": "添加多个水印失败", "error": stderr}
            
            if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
                log_info(f"多个水印添加成功，输出文件: {output_path}")
                return {
                    "success": True,
                    "message": "多个水印添加成功",
                    "output_path": output_path,
                    "video_info": video_info
                }
            else:
                log_error("输出文件生成失败或为空")
                return {"success": False, "message": "输出文件生成失败或为空"}
                
        except Exception as e:
            log_error(f"处理多个视频水印时发生错误: {e}")
            return {"success": False, "message": f"处理错误: {str(e)}"}
        finally:
            # 清理临时文件
            for temp_file in temp_files:
                try:
                    if os.path.exists(temp_file):
                        os.remove(temp_file)
                        log_info(f"已删除临时文件: {temp_file}")
                except Exception as e:
                    log_warning(f"删除临时文件失败: {e}")
                    
                    
                    
    def add_floating_image_watermark(
        self,
        video_path: str,
        output_path: str,
        image_path: str,
        opacity: float = 1,
        movement_type: str = "random",
        scale: float = 1.0,
        speed: float = 1.0
    ) -> Dict[str, Any]:
        """
        将透明浮动图片水印添加到视频。
        
        Args:
            video_path: 输入视频路径
            output_path: 输出视频路径
            image_path: 水印图片路径
            opacity: 不透明度 (0.0-1.0)
            movement_type: 移动类型 ("random", "diagonal", "bounce", "circular")
            scale: 图片缩放比例 (1.0表示原始大小)
            speed: 水印移动速度 (0.5-3.0)
            
        Returns:
            包含处理结果的字典
        """
        temp_files = []  # 存储需要清理的临时文件
        try:
            # 检查输入文件是否存在
            if not os.path.exists(video_path):
                return {"success": False, "message": f"输入视频不存在: {video_path}"}
                
            if not os.path.exists(image_path):
                return {"success": False, "message": f"输入图片不存在: {image_path}"}
            
            # 确保输出目录存在
            os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True)
            
            # 获取视频信息
            video_info = self._get_video_info(video_path)
            if not video_info["success"]:
                return video_info
            
            width = video_info["width"]
            height = video_info["height"]
            duration = video_info["duration"]
            
            # 获取图片信息
            image_info = self._get_image_info(image_path)
            if not image_info["success"]:
                return image_info
                
            image_width = image_info["width"] * scale
            image_height = image_info["height"] * scale
            
            # 生成水印移动表达式
            movement_expr = self._generate_movement_expression_for_image(
                width, height, image_width, image_height, movement_type, speed, duration
            )
            
            # 如果需要调整图片大小或透明度，创建预处理图片
            processed_image_path = self._preprocess_image(image_path, opacity, scale)
            if processed_image_path:
                temp_files.append(processed_image_path)
            else:
                processed_image_path = image_path
            
            # 构建FFmpeg命令
            cmd = self._build_ffmpeg_command_for_image(
                video_path, output_path, processed_image_path, movement_expr
            )
            
            # 执行FFmpeg命令
            log_info(f"开始添加浮动图片水印到视频: {video_path}")
            process = subprocess.Popen(
                cmd, 
                stdout=subprocess.PIPE, 
                stderr=subprocess.PIPE,
                universal_newlines=True
            )
            _, stderr = process.communicate()
            
            # 检查处理结果
            if process.returncode != 0:
                log_error(f"添加图片水印失败: {stderr}")
                return {"success": False, "message": "添加图片水印失败", "error": stderr}
            
            if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
                log_info(f"图片水印添加成功，输出文件: {output_path}")
                return {
                    "success": True,
                    "message": "图片水印添加成功",
                    "output_path": output_path,
                    "video_info": video_info
                }
            else:
                log_error("输出文件生成失败或为空")
                return {"success": False, "message": "输出文件生成失败或为空"}
                
        except Exception as e:
            log_error(f"处理图片水印时发生错误: {e}")
            return {"success": False, "message": f"处理错误: {str(e)}"}
        finally:
            # 清理临时文件
            for temp_file in temp_files:
                try:
                    if os.path.exists(temp_file):
                        os.remove(temp_file)
                        log_info(f"已删除临时文件: {temp_file}")
                except Exception as e:
                    log_warning(f"删除临时文件失败: {e}")
                    
                    
    def _get_image_info(self, image_path: str) -> Dict[str, Any]:
        """获取图片的基本信息"""
        try:
            img = cv2.imread(image_path, cv2.IMREAD_UNCHANGED)
            if img is None:
                return {"success": False, "message": "无法打开图片文件"}
            
            height, width = img.shape[:2]
            has_alpha = img.shape[2] == 4 if len(img.shape) > 2 else False
            
            return {
                "success": True,
                "width": width,
                "height": height,
                "has_alpha": has_alpha
            }
        except Exception as e:
            log_error(f"获取图片信息失败: {e}")
            return {"success": False, "message": f"获取图片信息失败: {str(e)}"}

    def _preprocess_image(self, image_path: str, opacity: float, scale: float) -> Optional[str]:
        """预处理图片：调整大小和透明度"""
        if opacity == 1.0 and scale == 1.0:
            return None  # 不需要处理
            
        try:
            # 读取图片
            img = cv2.imread(image_path, cv2.IMREAD_UNCHANGED)
            if img is None:
                log_error(f"无法读取图片: {image_path}")
                return None
                
            # 调整大小
            if scale != 1.0:
                new_width = int(img.shape[1] * scale)
                new_height = int(img.shape[0] * scale)
                img = cv2.resize(img, (new_width, new_height), interpolation=cv2.INTER_AREA)
            
            # 调整透明度
            if opacity != 1.0:
                # 如果图片有alpha通道
                if img.shape[2] == 4:
                    # 直接调整alpha通道
                    img[:, :, 3] = (img[:, :, 3] * opacity).astype(np.uint8)
                else:
                    # 为RGB图片添加alpha通道
                    alpha = np.ones(img.shape[:2], dtype=np.uint8) * int(255 * opacity)
                    img = cv2.merge((img[:, :, 0], img[:, :, 1], img[:, :, 2], alpha))
            
            # 保存处理后的图片
            output_path = os.path.join(self.temp_dir, f"processed_watermark_{int(time.time()*1000)}.png")
            cv2.imwrite(output_path, img)
            
            return output_path
        except Exception as e:
            log_error(f"处理图片失败: {e}")
            return None

    def _generate_movement_expression_for_image(
        self,
        width: int,
        height: int,
        image_width: int,
        image_height: int,
        movement_type: str,
        speed: float,
        duration: float
    ) -> Dict[str, str]:
        """
        生成图片水印移动的表达式
        
        Args:
            width: 视频宽度
            height: 视频高度
            image_width: 水印图片宽度
            image_height: 水印图片高度
            movement_type: 移动类型
            speed: 移动速度
            duration: 视频时长
        
        Returns:
            包含x和y表达式的字典
        """
        speed = speed * 100
        
        # 计算安全活动区域
        margin_x = image_width * 0.1 + 20  # 额外安全边距
        margin_y = image_height * 0.1 + 20
        
        min_x = margin_x
        max_x = width - image_width - margin_x
        min_y = margin_y
        max_y = height - image_height - margin_y
        
        # 检查活动区域是否有效
        if max_x <= min_x or max_y <= min_y:
            # 如果图片太大，无法满足安全边距，则缩小边距
            min_x = 10
            max_x = width - image_width - 10
            min_y = 10
            max_y = height - image_height - 10
            
            log_warning(f"图片尺寸过大或视频分辨率过小，减少安全边距: x({min_x:.1f}-{max_x:.1f}), y({min_y:.1f}-{max_y:.1f})")
            
            # 如果仍然无效，则使用固定位置
            if max_x <= min_x or max_y <= min_y:
                log_warning("无法找到合适的活动区域，使用中心固定位置")
                return {
                    "x": f"(W-w)/2",
                    "y": f"(H-h)/2"
                }
        
        # 计算活动区域中心点和范围
        x_center = (min_x + max_x) / 2
        y_center = (min_y + max_y) / 2
        x_range = max(1, (max_x - min_x) / 2.5)
        y_range = max(1, (max_y - min_y) / 2.5)
        
        # 调整速度
        adjusted_speed = speed * 0.03  # 基础移动速度
        
        # 根据移动类型生成表达式
        expressions = {"x": f"{x_center}", "y": f"{y_center}"}        
        if movement_type == "random":
            # 随机轨迹 - 使用多个正弦/余弦函数叠加
            time_factor = adjusted_speed * 0.1
            
            basic_x = f"{x_center}+{x_range}*((sin(t*{time_factor})+sin(t*{time_factor*0.37})+sin(t*{time_factor*0.18}))/3)"
            basic_y = f"{y_center}+{y_range}*((cos(t*{time_factor*0.29})+cos(t*{time_factor*0.13})+cos(t*{time_factor*0.21}))/3)"
            
            expressions["x"] = basic_x
            expressions["y"] = basic_y
        elif movement_type == "circular":
            # 圆周运动
            time_factor = adjusted_speed * 0.1
            expressions["x"] = f"{x_center}+{x_range}*sin(t*{time_factor})"
            expressions["y"] = f"{y_center}+{y_range}*cos(t*{time_factor})"
        elif movement_type == "diagonal":
            # 对角线移动
            time_factor = adjusted_speed * 0.05
            period = 10 / time_factor
            expressions["x"] = f"{x_center}+{x_range}*sin(t*{time_factor})"
            expressions["y"] = f"{y_center}+{y_range}*sin(t*{time_factor})"
        
        # 应用最终安全边界检查
        expressions["x"] = f"min(max({expressions['x']}, 10), {width}-{image_width}-10)"
        expressions["y"] = f"min(max({expressions['y']}, 10), {height}-{image_height}-10)"
        
        return expressions

    def _build_ffmpeg_command_for_image(
        self,
        input_path: str,
        output_path: str,
        image_path: str,
        movement_expr: Dict[str, str]
    ) -> List[str]:
        """构建FFmpeg命令用于图片水印"""
        # 构建overlay滤镜
        overlay_filter = f"overlay=x='{movement_expr['x']}':y='{movement_expr['y']}'"
        
        # 构建完整的FFmpeg命令
        cmd = [
            self.ffmpeg_path,
            "-y",  # 覆盖输出文件（如果存在）
            "-i", input_path,
            "-i", image_path,
            "-filter_complex", overlay_filter,
            "-c:v", "libx264",  # 使用H.264编码
            "-crf", "23",       # 设置视频质量
            "-preset", "medium",  # 编码速度和质量的平衡
            "-c:a", "copy",     # 直接复制音频流
            output_path
        ]
        
        return cmd
    